package com.snopy.thread.cyclicbarrier;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author snopy
 * @version 1.0.0
 * @classname BankWaterService
 * @description
 * @email 77912204@qq.com
 * @date 2022/11/19 16:41
 */
public class BankWaterService implements Runnable{

    /*
    * 创建4个屏障，处理完成之后执行当前类的run方法
    * */
    private final CyclicBarrier c;
    /*
    * 假设只有4个sheet,所以只启动4个线程
    * */
    private Executor executor;
    final BufferedReader[] in = new BufferedReader[4];
    public BankWaterService(Integer cnum, Executor executor) {
        this.c = new CyclicBarrier(cnum,this);
        this.executor = executor;
    }

    private ConcurrentHashMap<String,Integer> sheetBankWaterCount = new ConcurrentHashMap<>();
    private void count(){


        for (int i = 0;i<4;i++){
            AtomicInteger num = new AtomicInteger();
            int finalI = i;
            executor.execute(()->{
                try {
                    in[finalI] =  new BufferedReader(new FileReader("F:\\workspaceA\\Sonata\\Sonata_test\\src\\main" +
                            "\\resources\\abc"+ finalI +
                        ".txt"));
                    String s;
                    while ((s = in[finalI].readLine()) != null){
                        num.addAndGet(Integer.parseInt(s));
                    }
                } catch (IOException e) {

                    throw new RuntimeException(e);
                }
                //计算银行流水
                sheetBankWaterCount.put(Thread.currentThread().getName(),num.get());
                try {
                    //计算完成，插入一个屏障
                    c.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    throw new RuntimeException(e);
                }
            });
        }

    }

    @Override
    public void run() {
        AtomicInteger result = new AtomicInteger();
        //汇总每个
        sheetBankWaterCount.forEach((s, integer) -> result.addAndGet(integer));
        sheetBankWaterCount.put("result",result.get());
        System.out.println(result.get());
        for (int j = 0; j < 4; j++) {
            if (in[j] != null){
                try {
                    in[j].close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        c.reset();
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        BankWaterService bankWaterService = new BankWaterService(4,executor);
        bankWaterService.count();
        Integer result = bankWaterService.sheetBankWaterCount.get("result");
        executor.shutdown();
        //20388
        //System.out.println(result);
    }
}
